#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h>

// 宏定义
#define MAXNUM 1000

 // 查找亲近同学
int find_closest_classmate(int *, int, const char *, const char *);
void output(int *, int); // 输出结果

// 测试
int main()
{
    // 声明变量
    int mno;
    char like[27]; // 26个大写字符+'\0'
    char classmate[MAXNUM + 1];  // MAXNUM个同学+'\0'
    int sno[MAXNUM];

    mno = 1;
    strcpy(like, "ABC");
    strcpy(classmate, "BPTYHJKAMNBPHC");

    // 处理数据
    int n = find_closest_classmate(sno, mno, like, classmate);

    // 输出结果
    output(sno, n);

    return 0;
}

// 查找亲近同学
int find_closest_classmate(int *sno, int myno,
                           const char *like,
                           const char *classmate)
{
    int n = 0;
    const char *p_str = NULL;
    size_t offset;

    // 正则处理相关变量
    char err_buf[256] = {0};
    int c;
    const size_t nmatch = 1;
    regmatch_t pmatch[1];
    regex_t pat_buf;

    // 构造正则表达式
    char *pat = (char*)malloc((strlen(like) + 2 + 1) * sizeof(char));
    if(pat == NULL)
    {
        printf("not enough memory!\n");
        exit(EXIT_FAILURE);
    }

    memset(pat, 0, (strlen(like) + 2 + 1) * sizeof(char));
    pat[0] = '[';
    strcat(pat, like);
    strcat(pat, "]");

    // 编译正则表达式
    c = regcomp(&pat_buf, pat, REG_EXTENDED);
    // 正则表达式编译出错
    if(c != 0)
    {
        printf("error on compiling regex.code = %d\n", c);
        regerror(c, &pat_buf, err_buf, sizeof(err_buf));
        err_buf[sizeof(err_buf) - 1] = '\0';
        printf("error: %s\n", err_buf);

        exit(EXIT_FAILURE);
    }

    // 起始匹配的偏移量
    offset = 0;

    do
    {
        // 正则表达式匹配的起始地址
        p_str = classmate + offset;
        c = regexec(&pat_buf, p_str, nmatch, pmatch, 0);

        // 依次判断匹配情况
        if(c != 0)
        {
            /** 没有找到匹配，结束循环 */
            break;
        }
        else
        {
            // 只记录与自己学号不同的朋友(地址相减)
            if((p_str + pmatch[0].rm_so - classmate + 1) != myno)
            {
                sno[n] = p_str + pmatch[0].rm_so - classmate + 1;
                n++;
            }

            // 偏移量
            offset += pmatch[0].rm_eo;
            continue;
        }
    }while(1);

    // 释放空间
    regfree(&pat_buf);
    free(pat);

    return n; // 返回找到的亲近同学总数
}

// 输出结果
void output(int *sno, int n)
{
    int i;

    if(n > 0)
    {
        for(i = 0; i < n - 1; i++)
        {
            printf("%d ", sno[i]);
        }
        printf("%d\n", sno[i]); // 避免最后输出多1个空格
    }
    else
    {
        printf("Lonely Xiao Ming\n");
    }
}
